package com.ym.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.baidu.aip.face.AipFace;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.ImmutableMap;
import com.ym.config.BaiduFaceConfig;
import com.ym.entity.SysUser;
import com.ym.response.Result;
import com.ym.service.SysUserService;
import com.ym.utils.ImageToBase64Util;
import org.apache.commons.collections.MapUtils;
import org.json.JSONObject;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private AipFace aipFace;
    @Autowired
    private BaiduFaceConfig baiduFaceConfig;

    @PostMapping("/login")
    public Result<String> login(@RequestBody SysUser user) {
        SysUser one = sysUserService.getOne(
                new LambdaQueryWrapper<>(SysUser.class)
                        .eq(SysUser::getUserName, user.getUserName())
                        .eq(SysUser::getDelFlag, false)
        );
        return Optional.ofNullable(one)
                .map(i -> {
                    if ( BCrypt.checkpw(user.getPassword(),i.getPassword()) ) {
                        StpUtil.login(i.getId());
                        return Result.ok(StpUtil.getTokenInfo().getTokenValue());
                    }
                    return Result.<String>fail(404,"密码错误");
                })
                .orElse(Result.fail(404,"未能找到该用户"));
    }

    // 人脸注册
    @PostMapping("/addUser")
    public Result<String> addUser(@RequestParam("file") MultipartFile file, @RequestParam("userId")String userId){
        SysUser sysUser = sysUserService.getById(userId);
        return Optional.ofNullable(sysUser)
                .map(i -> {
                    JSONObject res = aipFace.addUser(
                            ImageToBase64Util.getImageBase64(file),
                            "BASE64",
                            baiduFaceConfig.getGroupId(),
                            userId,
                            null);
                    return Optional.ofNullable(res)
                            .filter(r -> r.optInt("error_code", -1) == 0)
                            .map(r -> r.optJSONObject("result"))
                            .map(result -> Result.ok("注册成功"))
                            .orElse(Result.fail(500, "注册失败"));
                })
                .orElse((Result.fail(404,"未能找到该用户")));
    }

    // 人脸搜索
    @PostMapping("/search")
    public Result<List<Map<String, String>>> search(@RequestParam("file") MultipartFile file){
        HashMap<String, Object> options = new HashMap<>();
        options.put("liveness_control", "LOW");

        JSONObject res = aipFace.search(
                ImageToBase64Util.getImageBase64(file),
                "BASE64",
                baiduFaceConfig.getGroupId(),
                options);
        return Optional.ofNullable(res)
                .filter(r -> r.optInt("error_code", -1) == 0)
                .map(r -> r.optJSONObject("result"))
                .map(result -> result.optJSONArray("user_list"))
                .filter(list -> list.length() > 0)
                .map(list -> IntStream.range(0, list.length())
                        .mapToObj(list::optJSONObject)
                        .filter(Objects::nonNull)
                        .filter(obj -> obj.has("score") && obj.getDouble("score") > 90)
                )
                .map(stream -> stream
                        .map(obj -> {
                            String userId = obj.getString("user_id");
                            SysUser sysUser = sysUserService.getById(userId);
                            return Optional.ofNullable(sysUser)
                                    .map(user -> (Map<String, String>) ImmutableMap.of(
                                            "userId",
                                            userId,
                                            "userName",
                                            user.getUserName(),
                                            "userInfo",
                                            obj.getString("user_info"))
                                    )
                                    .orElseGet(HashMap::new);
                        })
                        .filter(MapUtils::isNotEmpty)
                        .collect(Collectors.toList())
                )
                .map(Result::ok)
                .orElse(Result.fail(404, "未找到匹配的用户"));
    }

    @GetMapping("/isLogin")
    public Result<String> isLogin() {
        return Result.ok("当前会话是否登录：" + StpUtil.isLogin());
    }

    // 可以在方法上面添加指定角色跟权限，搭配网关统一鉴权实现双拦截
    @SaCheckRole("common")
    @SaCheckPermission("test:permission")
    @GetMapping(value = "/test")
    public Result<String> test() {
        System.out.println("----------");
        throw new RuntimeException("test");
    }

    @GetMapping("/logout")
    public Result<String> logout() {
        StpUtil.logout();
        return Result.ok("登出成功");
    }
}
